A typical e-commerce Internet website has a web server and an application server, collectively referred to as a web application server. The web server acts as a front end to receive requests from the customer's web browser, or client. These requests can require the execution of complex business logic, which is typically handled by a back end application server. The application server carries out any necessary processing and generates output which is delivered via the web server back to the web browser in the form of a response.
Requests in the e-commerce context are typically initiated when the customer clicks or otherwise activates a hyperlink (link), button, or other device on a web page displayed by the client. The request usually contains a universal resource locator (URL) identifying a resource located on the web application server, and other information to identify the client or the nature of the request. When a request is submitted by a client to a web application server for processing, a connection is established between the web server and the client so that the server can return the response to the client over an open connection between the server and client, in accordance with Internet protocol. Because the protocol used to handle communications between clients and servers on the Internet (HTTP, or hypertext transfer protocol) is stateless, it is difficult to synchronize client-server communications. Under standard HTTP protocols, when a client submits a new request to a web application server while the server is still processing a previous request from the same client, the connection between the server and the client associated with the previous request is closed and a new connection for providing a response to the new request is established. The web application server will start processing the business (or application) logic associated with the new request. The server is unable to detect that the connection has been closed for the previous request. Therefore, at the same time the application server will continue to process the business logic associated with the previous request. This results in a waste of server resources because there is no open connection to which to write the result of the previous request back to the browser.
In particular, where the server requires a non-trivial amount of time to process the previous (or first) request, before a response is sent to the browser the customer may initiate multiple requests. These multiple requests may be initiated by multiple clicks on the same link or button on a web page, or successive activation of different links or buttons on the web page which make the identical request (for example, a graphical link and a text link may initiate the same request). A link typically invokes a command, which usually represents a particular business (application) logic in the application server. Multiple clicks on a particular link will cause the same command to be executed.
These multiple requests result in a waste of resources as each separate request causes the application server to allocate a new thread for each instance where business (application) logic processing is required. A large number of requests caused by a large number of clicks may have the effect of creating a denial of service attack on the server by occupying all available server resources. Multiple requests may also result in unexpected output displayed on the web browser or misleading results for the customer.
For example, in an e-commerce shopping cart scenario, a user might have selected items to be placed in her virtual shopping cart, and then clicked on the checkout button. If the server response is slow due to network conditions, or other reasons, the user might click on the checkout button a number of times, thinking that this will accelerate the checkout process or speed up the loading of the next page. However, when the first checkout request was submitted the server started processing the items in the shopping cart and placed them in a state where checkout processing could not be applied to the items again. Therefore, each subsequent click by the user will generate a request which will result in failures to complete the checkout process. In the meantime, when the first checkout process is complete, the connection between the server and the client for returning the first response to the user will have been closed. As the only valid connection is from the last request whose processing failed, the user will only see a failure of the request. Web application server resources are also wasted on checkout submissions made between the first and last request.
Solutions have been proposed to this problem which make use of either client-side programs or synchronization tokens. Multiple requests through buttons and forms on a web page may be handled by implementing JavaScript programming to handle form submission, but this requires the client browser must be JavaScript-enabled for this solution to function. Moreover, the solution is limited to web page forms. An alternative solution proposed in Core J2EE Patterns: Best Practices and Design Strategies by Alur et al. is to provide a synchronization token which is stored by both the client and the server. The token is submitted by the client on every request made through a web page form and must be compared to the token stored on the server before the request is processed. Again, this solution is limited to forms, and does not prevent multiple submissions of identical requests.